【企微开发最佳实践】Java企业微信应用开发SDK | 您所在的位置:网站首页 › wecom v30 › 【企微开发最佳实践】Java企业微信应用开发SDK |
经过两年多业余时间断断续续的开发,基于Java Spring生态的企业微信API SDK类库wecom-sdk终于具备生产就绪能力了。该类库屏蔽了复杂性,高度抽象了请求模型,通用性和扩展性兼具。大大降低了开发人员的学习使用成本。 Github: https://github.com/NotFound403/wecom-sdkGitee: https://gitee.com/felord/wecom-sdk现在已经开源并托管到Maven中央仓库,请使用最新版本: cn.felord wecom-sdk ${wecom.sdk.version} 目前自建应用已经能够满足大部分场景,第三方还在开发中。接下来对核心的一些概念和用法进行一些介绍,方便大家入门。 入门这里屏蔽了一些繁琐的步骤,开发者只需要做好配置即可调用。以下是调用企业群发API向客户群发送图文的例子: //① 应用参数组装 建议持久化并使用缓存层 AgentDetails externalAgent = DefaultAgent.nativeAgent("企业ID", "应用密钥", NativeAgent.EXTERNAL); //② 定义缓存 全局定义一次即可 WeComTokenCacheable weComTokenCacheable = new Cache(); //③ 初始化API入口,建议注入Spring IoC WorkWeChatApi wecom = new WorkWeChatApi(weComTokenCacheable); //④ 检索具体的API ExternalContactManager externalContactManager = wecom.externalContactManager(externalAgent); //⑤ 组织参数 MsgTemplateRequest request = new MsgTemplateRequest(ChatType.GROUP); ContentText text = new ContentText("测试企业向客户群发送信息"); request.setText(text); Link link = new Link(); link.setTitle("百度一下"); link.setDesc("遇到问题,百度一下"); link.setUrl("https://www.baidu.com"); link.setPicurl("https://www.baidu.com/img/pc_79b50cf376490.png"); request.setAttachments(Collections.singletonList(new LinkMsgAttachment(link))); request.setSender("zhangsan"); //⑥ 向企业微信服务器发起请求并获取响应结果 MsgTemplateResponse msgTemplateResponse = externalContactManager.messageApi() .addMsgTemplate(request); Integer errcode = msgTemplateResponse.getErrcode(); String errmsg = msgTemplateResponse.getErrmsg(); String msgid = msgTemplateResponse.getMsgid(); List failList = msgTemplateResponse.getFailList();步骤是不是非常简单,基本都是在组装参数。可能里面有几个概念大家会有疑惑,接下来我们对里面的一些重要概念进行一些说明。 AgentDetailscn.felord.AgentDetails 是对应用的抽象描述,包含了企业IDcorpId,应用IDagentId以及密钥secret,绝大多数接口的调用会用到它,默认实现是DefaultAgent。如果是自建应用你可以这样初始化: AgentDetails agent = new DefaultAgent("企业ID","应用密钥", "应用ID");如果是内置应用,比如外部联系人应用: AgentDetails external = DefaultAgent.nativeAgent("企业ID", "应用密钥", NativeAgent.EXTERNAL);通常这些应用参数会存入数据库,然后我们需要通过企业ID和应用ID实现应用配置检索服务(可以增加缓存来降低数据库的检索压力): (corpId,agentId) -> AgentDetails WeComTokenCacheable这个主要定义企业微信AccessToken、corpticket和agentticket中继缓存。这里我使用了Spring Cache实现,你可以自由选择,但是要自行保证中继服务器数据一致性。 public static class RedisWeComCacheable implements WeComTokenCacheable { private static final String QYWX_TOKEN_CACHE = "token::qywx"; private static final String QYWX_CORP_TICKET_CACHE = "ticket::qywx::corp"; private static final String QYWX_AGENT_TICKET_CACHE = "ticket::qywx::agent"; @CachePut(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putAccessToken(@NotNull String corpId, @NotNull String agentId, @NotNull String accessToken) { return accessToken; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getAccessToken(@NotNull String corpId, @NotNull String agentId) { return null; } @CachePut(value = {QYWX_CORP_TICKET_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putCorpTicket(@NotNull String corpId, @NotNull String agentId, @NotNull String corpTicket) { return corpTicket; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getCorpTicket(@NotNull String corpId, @NotNull String agentId) { return null; } @CachePut(value = {QYWX_AGENT_TICKET_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String putAgentTicket(@NotNull String corpId, @NotNull String agentId, @NotNull String agentTicket) { return agentTicket; } @Cacheable(value = {QYWX_TOKEN_CACHE}, key = "#corpId.concat('::').concat(#agentId)") @Override public String getAgentTicket(@NotNull String corpId, @NotNull String agentId) { return null; } } WorkWeChatApiWorkWeChatApi是企业微信API的唯一入口,推荐注入Spring IoC,然后就可以通过它的一系列方法来实现企业微信提供的功能了。例如通过手机号查询成员的企业微信userid: AgentDetails agent = DefaultAgent.nativeAgent("企业ID", "通讯录secret", NativeAgent.CONTACT); GenericResponse userIdByMobile = wecom.contactBookManager(agent) .userApi() .getUserIdByMobile("这里为手机号"); String userId = userIdByMobile.getData(); 回调回调的处理通过CallbackCrypto来负责,它屏蔽了验签、解密、异步处理等技术难点,你可以通过CallbackCryptoBuilder构建CallbackCrypto,并把CallbackCrypto注入Spring IoC。 CallbackCryptoBuilderCallbackCryptoBuilder有几个关键点: XmlReader XML解析的抽象,框架默认提供了XStream实现,不喜欢的可以重新实现注入。Consumer 消费事件函数,用来处理回调数据。CallbackSettingsService 企业微信回调配置检索,用来检索回调的配置参数。ExecutorService 回调处理线程池,回调数据的处理是异步的,这里默认提供了一个名字为WECOM-CALLBACK-THREAD-POOL的线程池,你也可以自定义一个符合你实际配置的线程池。参考示例: @Bean public CallbackCrypto callbackCrypto(IEventRecordService eventRecordService, IWeCallbackSettingsService callbackSettingsService) { return new CallbackCryptoBuilder(eventRecordService::handleCallbackEvent) .build(callbackSettingsService::getByAgentIdAndCorpId); } 回调示例通用回调参考示例: @RestController @RequestMapping("/wecom/callback") public class CallbackController { /** * The Callback crypto. */ @Autowired CallbackCrypto callbackCrypto; /** * 验证回调URL * * @param msgSignature the msg signature * @param timestamp the timestamp * @param nonce the nonce * @param echostr the echostr * @param corpId the corp id * @param agentId the agent id * @return the long */ @GetMapping("/{corpId}/{agentId}") public String verifyUrl(@RequestParam("msg_signature") String msgSignature, @RequestParam String timestamp, @RequestParam String nonce, @RequestParam String echostr, @PathVariable String corpId, @PathVariable String agentId) { return callbackCrypto.decryptMsg(agentId,corpId,msgSignature, timestamp, nonce, echostr); } /** * 消费回调数据 * * @param msgSignature the msg signature * @param timestamp the timestamp * @param nonce the nonce * @param xmlBody the xml body * @param corpId the corp id * @param agentId the agent id * @return the string */ @PostMapping("/{corpId}/{agentId}") public String consume(@RequestParam("msg_signature") String msgSignature, @RequestParam String timestamp, @RequestParam String nonce, @RequestBody String xmlBody, @PathVariable String corpId, @PathVariable String agentId) { return callbackCrypto .accept(msgSignature, timestamp, nonce, xmlBody); } } 总结wecom-sdk总体的设计思路是屏蔽复杂度,提升可用性,并保持可扩展,可复用的理念设计。有兴趣的Java开发者可以参考使用,也欢迎提出意见和参与贡献。 |
CopyRight 2018-2019 实验室设备网 版权所有 |